/**
    Copyright (c) 2010 ATTi 
    All rights reserved.
    Author: Michael Shu
    Date: 8/12/2010
*/

@isTest
private class BatchUpdateAccountTeamTester {
	private static String CMRAgencyRecordTypeName = 'CMR Agency';
    private static String CMRAgencyClientRecordTypeName = 'CMR Agency Client';
	private static String CMRAgencyRecordTypeId =RecordTypeHelper.GetRecordTypeID('Account',  CMRAgencyRecordTypeName);
	private static String CMRAgencyClientRecordTypeId = RecordTypeHelper.GetRecordTypeID('Account', CMRAgencyClientRecordTypeName);

    private static Integer Num_Account = 10;
	private static Integer Num_AccountTeam = 3;
	private static List<User> userList;
	private static Map<Id, Account> CMRAccounts;
	private static Map<Id, Account> CMRClientAccounts;
	private static User sysAdmins;

	private static void addUsers(){
		List<Profile> profiles = [select ID, Name from Profile where Name =: 'National Sales' 
		                                                          or Name =: 'National Sales Assignment Manager' 
		                                                          or Name =: 'National Sales Management'];
		List<UserRole> userroles = [select ID, Name from UserRole where Name =: 'National Sales Operations Manager'
		                                                             or Name =: 'National Sales Operations Director'
		                                                             or Name =: 'General Sales Manager'];
		List<User> users = new List<User>();
		Integer i = 0;
		for(Profile p : profiles){
			for(UserRole r : userroles){
				User u_new = new User();
				u_new.UserName = 'xyz_1234567890@atti-temp.com' + i;
				u_new.LastName = 'Michael Shu Test ' + i;
				u_new.Email = 'xyz_1234567890@atti.com';
				u_new.Alias = 'abcde' + i;
				u_new.CommunityNickname = 'xyaz_1234556' + i;
				u_new.TimeZoneSidKey = 'America/Los_Angeles';
				u_new.LocaleSidKey = 'en_US';
				u_new.EmailEncodingKey = 'UTF-8';
				u_new.ProfileId = p.Id;
				u_new.UserRoleId = r.Id;
				u_new.LanguageLocaleKey = 'en_US';
				users.add(u_new);
				i++;
			}
		}
		Database.Saveresult[] lsr = Database.insert(users);
		Set<ID> uIDs = new Set<ID>();
		for(Database.Saveresult sr : lsr){
			uIDs.add(sr.getID());
		}
		userList = [select ID from User where ID IN: uIDs];	
		
		User u_new = new User();
		u_new.UserName = 'xyz_1234567890@atti-temp.com';
		u_new.LastName = 'Michael Shu Admin Test';
		u_new.Email = 'admin-null@atti.com';
		u_new.Alias = 'admin_me';
		u_new.CommunityNickname = 'admin123456' + i;
		u_new.TimeZoneSidKey = 'America/Los_Angeles';
		u_new.LocaleSidKey = 'en_US';
		u_new.EmailEncodingKey = 'UTF-8';
		u_new.ProfileId = [select ID from Profile where Name =: 'System Administrator' limit 1].Id;
		u_new.UserRoleId = [select ID from UserRole where Name =: 'Information Systems' limit 1].Id;
		u_new.LanguageLocaleKey = 'en_US';
		Database.Saveresult u_sr = Database.insert(u_new);	
		sysAdmins = [select ID from User where ID =: u_sr.getID() limit 1];		
	}
		
	private static void init(){	
		addUsers();
		// CMR Account
		List<Account> accts = new List<Account>();
		for(Integer i= 0; i < Num_Account; i++){
			Account a = new Account();
			a.Name = 'CMR Account Test ' + i;
			a.RecordTypeId = CMRAgencyRecordTypeId;
			a.CMR_ID__c = '90045' + i;
			accts.add(a);
		}	
		Database.Saveresult[] sr_acct;
		System.runAs(sysAdmins){
			sr_acct = Database.insert(accts);
		}
		Set<ID> accIDs = new Set<ID>();
		for(Database.Saveresult sr : sr_acct){
			accIDs.add(sr.getID());
		}
		CMRAccounts = new Map<Id, Account>([select ID from Account where ID IN: accIDs]);
		
		// CMR Client Account
		accts = new List<Account>();
		for(Integer i= 0; i < Num_Account; i++){
			Account a = new Account();
			a.Name = 'CMR Client Account Test ' + i;
			a.Agency__c = CMRAccounts.values()[i].Id;
			a.RecordTypeId = CMRAgencyClientRecordTypeId;
			accts.add(a);
		}	
		System.runAs(sysAdmins){
			sr_acct = Database.insert(accts);
		}
		accIDs = new Set<ID>();
		for(Database.Saveresult sr : sr_acct){
			accIDs.add(sr.getID());
		}
		CMRClientAccounts = new Map<Id, Account>([select ID from Account where ID IN: accIDs]);	
		
		// Account Team	
		List<AccountTeamMember> accTeams = new List<AccountTeamMember>();
		Integer j = 0;
		for(Account a : CMRClientAccounts.values()){
			for(Integer i= 0; i < Num_AccountTeam; i++){
				AccountTeamMember at = new AccountTeamMember();
				at.AccountId = a.Id;
				at.TeamMemberRole = 'Test Manager ' + i;
				Integer times = j/userList.size();
				Integer index = j - times*userList.size();
				at.UserId = userList[index].Id;
				accTeams.add(at);
				j++;
			}
		}
		System.runAs(sysAdmins){
			sr_acct = Database.insert(accTeams);
		} 			
	}
	
    public static testMethod void schedulerTest() {
    	init();
		Test.startTest();
    	BatchUpdateSchedulerDaily b0 = new BatchUpdateSchedulerDaily();
    	String sch0 = BatchUpdateSchedulerDaily.CRON_EXP0;
    	String jobId;
    	System.runAs(sysAdmins){
    		jobId = System.schedule('Test Schedule Job0', sch0, b0);
    	}
    	CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
    	System.assertEquals(BatchUpdateSchedulerDaily.CRON_EXP0, ct.CronExpression); 
    	System.assertEquals(0, ct.TimesTriggered);
    	Date d = Date.today();
    	d = d.addDays(1);
    	String dateStr = String.valueOf(d); 	
    	System.assertEquals(dateStr + ' 00:00:00', String.valueOf(ct.NextFireTime));
    	Test.stopTest();
    }

    public static testMethod void schedulerPart2Test() {
    	init();
		Test.startTest();
    	BatchUpdateSchedulerPart2 p2 = new BatchUpdateSchedulerPart2();
    	String sch0 = BatchUpdateSchedulerDaily.CRON_EXP0;
    	String jobId;
    	System.runAs(sysAdmins){
    		jobId = System.schedule('Test Schedule Job0', sch0, p2);
    	}
    	CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
    	System.assertEquals(BatchUpdateSchedulerDaily.CRON_EXP0, ct.CronExpression); 
    	System.assertEquals(0, ct.TimesTriggered);
    	Date d = Date.today();
    	d = d.addDays(1);
    	String dateStr = String.valueOf(d); 	
    	System.assertEquals(dateStr + ' 00:00:00', String.valueOf(ct.NextFireTime));
    	Test.stopTest();
    }

    public static testMethod void schedulerPart3Test() {
    	init();
		Test.startTest();
    	BatchUpdateSchedulerPart3 p3 = new BatchUpdateSchedulerPart3();
    	String sch0 = BatchUpdateSchedulerDaily.CRON_EXP0;
    	String jobId;
    	System.runAs(sysAdmins){
    		jobId = System.schedule('Test Schedule Job0', sch0, p3);
    	}
    	CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
    	System.assertEquals(BatchUpdateSchedulerDaily.CRON_EXP0, ct.CronExpression); 
    	System.assertEquals(0, ct.TimesTriggered);
    	Date d = Date.today();
    	d = d.addDays(1);
    	String dateStr = String.valueOf(d); 	
    	System.assertEquals(dateStr + ' 00:00:00', String.valueOf(ct.NextFireTime));
    	Test.stopTest();
    }
            
    public static testMethod void batchUpdateAccountTeamTest() {
    	Integer scope = 200;
    	init();
    	DateTime begin_time = DateTime.now();
    	System.runAs(sysAdmins){
	    	Test.startTest();
			BatchUpdateAccountTeam clean_acct = new BatchUpdateAccountTeam(BatchUpdateAccountTeam.CleanAccountTeam);
			Id clean_acct_id = database.executebatch(clean_acct, scope);
			BatchUpdateAccountTeam aggregate_acct = new BatchUpdateAccountTeam(BatchUpdateAccountTeam.AggregateAccountTeam);
			Id aggregate_acct_id = database.executebatch(aggregate_acct, scope);
	    	Test.stopTest();
    	}
    	DateTime stop_time = DateTime.now();
    	System.debug('stop_time.getTime() - begin_time.getTime() = ' + (stop_time.getTime() - begin_time.getTime()));
    	
    	List<AccountTeamMember> CMRClientAccountTeamMembers = [select ID, Account.Agency__c, User.Name, TeamMemberRole
    	                                                       from AccountTeamMember where AccountId IN: CMRClientAccounts.keySet()];			 	
    	List<AccountTeamMember> accountTeamsCMR = [select ID, AccountId, User.Name, TeamMemberRole
    	                                           from AccountTeamMember where AccountId IN: CMRAccounts.keySet()];
    	Map<ID, Set<String>> CMRAccountTeams = new Map<ID, Set<String>>();
    	
    	for(AccountTeamMember at1 : accountTeamsCMR){
    		Set<String> unames;
    		if(CMRAccountTeams.containsKey(at1.AccountId)){
    			unames = CMRAccountTeams.get(at1.AccountId);
    		}else{
    			unames = new Set<String>();
    		}
    		unames.add(at1.User.Name);
    		CMRAccountTeams.put(at1.AccountId, unames);
    	}
    	
    	for(AccountTeamMember at2 : CMRClientAccountTeamMembers){
    		Set<String> userNames = CMRAccountTeams.get(at2.Account.Agency__c);
    		//System.assertEquals(true, userNames.contains(at2.User.Name));
    	}
    }
    
    public static testMethod void batchUpdateAddAndRemoveAccoutFollowersInChatter() {
    	Integer scope = 200;
    	init();
    	DateTime begin_time = DateTime.now();
    	System.runAs(sysAdmins){
	    	Test.startTest();
	    	BatchUpdateAccountTeam addremovefolloers = new BatchUpdateAccountTeam(BatchUpdateAccountTeam.AddAndRemoveAccoutFollowersInChatter);
	    	Id addremovefolloers_id = database.executebatch(addremovefolloers, scope);
	    	Test.stopTest();
    	}
    	DateTime stop_time = DateTime.now();    	
    	
    }
}